﻿using Alta.Class;
using Hardcodet.Wpf.TaskbarNotification;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO.Ports;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace Camera
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private TaskbarIcon notifyIcon;
        public static setting @setting;
        public static string fileSetting = "setting.xml";

        public int TIME_SLEEP = 3000;
        const int BAUDRATE = 9600;
        const int DATABITS = 8;
        private List<SerialPort> listSerialPort;
        private string cmd = "";
        private Thread sqlThread;
        private Command command;
        public static bool alert = false;
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
            setting = setting.read(fileSetting);
            if (setting.time > 500)
            {
                TIME_SLEEP = setting.time;
            }

            mysql_helpper.connection(setting.user, setting.host, setting.pass, setting.database);
            this.MainWindow = new MainWindow();
            this.MainWindow.Show();


            this.listSerialPort = new List<SerialPort>();
            sqlThread = new Thread(RunMysqlThread);
            sqlThread.IsBackground = true;
            sqlThread.Start();

            var listCom = getListCOM();
            if (listCom.Length > 0)
            {
                if (App.setting.mode == AppMode.AUTO)
                {
                    foreach (string i in listCom)
                    {
                        SerialPort serialPort = new SerialPort();
                        serialPort = new SerialPort();
                        serialPort.openCOM(i, BAUDRATE, DATABITS, StopBits.One);
                        serialPort.DataReceived += serialPort_DataReceived;
                        serialPort.sendCommand("#0$");
                        this.listSerialPort.Add(serialPort);
                    }
                }
            }

        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            bool flag = true;
            char[] charsToTrim = { '\n' };
            SerialPort s = sender as SerialPort;
            string tmp = s.ReadExisting().Trim(charsToTrim);
            if (tmp.IndexOf("#") >= 0)
            {
                this.cmd = string.Empty;
                this.cmd += tmp;
                flag = false;
            }
            if (tmp.IndexOf("$") >= 0)
            {
                this.cmd += tmp;
                int to = this.cmd.IndexOf("#");
                if (to >= 0)
                {
                    int from = this.cmd.IndexOf("$");
                    this.cmd = this.cmd.Substring(to+1, from - to-1);
                }
                char[] tmpS = { ' ' };
                string[] element = this.cmd.Split(tmpS);
                if (element.Length == 4)
                {
                    if ((element[1] == "A" || element[1] == "B") && (element[3] == "1") && element.Length < 5)
                    {
                        alert = true;
                        this.Dispatcher.Invoke(DispatcherPriority.Background,
                            new Action(
                                  delegate()
                                  {
                                      if (this.MainWindow != null)
                                          (this.MainWindow as MainWindow).Alert = true;
                                  }));

                    }
                }
                Console.WriteLine(this.cmd);
                Regex myRegex = new Regex(@"\w$");
                if (!myRegex.IsMatch(this.cmd) && !string.IsNullOrEmpty(this.cmd))
                {
                    s.sendCommand(element[0] + " OK$");
                }
                else if (!string.IsNullOrEmpty(this.cmd) && this.command != null)
                {
                    if (s.PortName.ToLower() == command.name.ToLower() && command.mode == CommandMode.WAIT)
                    {
                        command.mode = CommandMode.RUN;
                    }
                }
                mysql_helpper.setCommand(this.cmd, s.PortName.ToString());
                flag = false;
                this.cmd = string.Empty;

            }
            if (flag)
                this.cmd += tmp;
        }

        private string[] getListCOM()
        {

            try
            {
                return System.IO.Ports.SerialPort.GetPortNames().OrderBy(m => m).ToArray();
            }
            catch (Exception)
            {
                return new string[0];
            }
        }

        private void RunMysqlThread()
        {
            while (true)
            {
                if (command == null || command.mode == CommandMode.RUN)
                {
                    command = mysql_helpper.getCommand();

                    if (command != null)
                    {
                        Console.WriteLine(command.content);
                        foreach (SerialPort s in this.listSerialPort)
                        {
                            if (s.PortName.ToLower() == command.name.ToLower())
                            {
                                s.sendCommand(command.content);
                                command.mode = CommandMode.WAIT;
                                char[] tmpS = { ' ' };
                                string[] element = this.command.content.Split(tmpS);
                                if (element.Length == 4)
                                {
                                    if ((element[1] == "C") && (element[3] == "0$") && element.Length < 5)
                                    {
                                        this.Dispatcher.Invoke(DispatcherPriority.Background,
                                            new Action(
                                                  delegate()
                                                  {
                                                      if (this.MainWindow != null)
                                                          (this.MainWindow as MainWindow).Alert = false;
                                                  }));

                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Null");
                    }
                }
                Thread.Sleep(TIME_SLEEP);
            }
        }

        protected override void OnExit(ExitEventArgs e)
        {
            notifyIcon.Dispose(); //the icon would clean up automatically, but this is cleaner
            base.OnExit(e);
        }

    }
}
